package br.com.devmedia.temppos.domain;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.hibernate.annotations.Type;

@Entity
@Table(name = "TB_PROJETO")
public class Projeto implements Serializable {

	private static final long serialVersionUID = 1L;
	
	@Id
	@GeneratedValue
	private Long codigo;
	
	@Column(name = "NOME", length = 80, nullable =  false)
	@Type(type = "org.hibernate.type.StringClobType")
	private String nome;
	
	@Column(name = "DESCRICAO", length = 80, nullable =  false)
	@Type(type = "org.hibernate.type.StringClobType")
	private String descricao;
	
	@Column(name = "DATA_INICIAL", nullable =  false)
	@Temporal(TemporalType.DATE)
	private Calendar dataInicial;
	
	@Column(name = "DATA_FINAL", nullable =  false)
	@Temporal(TemporalType.DATE)
	private Calendar dataFinal;
	
	@Column(name = "ATIVO", nullable =  false)
	private Boolean isAtivo;
	
	@ManyToOne(optional = false)
	@JoinColumn(name = "ID_SETOR", referencedColumnName = "CODIGO", nullable = false)
	private Setor setor;
	
	@OneToMany(mappedBy = "projeto", cascade = {CascadeType.ALL}, orphanRemoval = true)
	@LazyCollection(LazyCollectionOption.EXTRA) // Recupera tardiamento a colecao. Ele nao traz de vez, apenas quando eu os busco..
	@OrderBy(value = "CODIGO asc") // recupera dos dados pelo ID ascendente.
	private List<ProjetoFuncionario> listaProjetoFuncionario = new ArrayList<ProjetoFuncionario>();
			
	public Projeto() {
		
	}
	
	/***
	 * Responsavel por Salvar um novo Projeto de Funcionario na lista de Funcionarios cadastrados. 
	 */
	public void adicionarFuncionario(ProjetoFuncionario projetoFuncionarioParametro) {
		projetoFuncionarioParametro.setProjeto(this);
		this.listaProjetoFuncionario.add(projetoFuncionarioParametro);
	}
	
	/***
	 * Responsavel por Remover um Projeto de Funcionario passado por parametro. 
	 */
	public void removerFuncionario(ProjetoFuncionario projetoFuncionarioParamentro) {
		if(this.listaProjetoFuncionario.contains(projetoFuncionarioParamentro)) {
			this.listaProjetoFuncionario.remove(projetoFuncionarioParamentro);
		}
	}
	
	/***
	 * Responsavel por Remover todos os Funcionarios da lista de funcionarios. 
	 */
	public void removerTodosFuncionario() {
		this.listaProjetoFuncionario.clear();
	}
	
	public Long getCodigo() {
		return codigo;
	}
	public void setCodigo(Long codigo) {
		this.codigo = codigo;
	}
	public String getNome() {
		return nome;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
	public String getDescricao() {
		return descricao;
	}
	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}
	public Calendar getDataInicial() {
		return dataInicial;
	}
	public void setDataInicial(Calendar dataInicial) {
		this.dataInicial = dataInicial;
	}
	public Calendar getDataFinal() {
		return dataFinal;
	}
	public void setDataFinal(Calendar dataFinal) {
		this.dataFinal = dataFinal;
	}
	public Boolean getIsAtivo() {
		return isAtivo;
	}
	public void setIsAtivo(Boolean isAtivo) {
		this.isAtivo = isAtivo;
	}
	public Setor getSetor() {
		return setor;
	}

	public void setSetor(Setor setor) {
		this.setor = setor;
	}

	public List<ProjetoFuncionario> getListaProjetoFuncionario() {
		return listaProjetoFuncionario;
	}

	public void setListaProjetoFuncionario(
			List<ProjetoFuncionario> listaProjetoFuncionario) {
		this.listaProjetoFuncionario = listaProjetoFuncionario;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((codigo == null) ? 0 : codigo.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Projeto other = (Projeto) obj;
		if (codigo == null) {
			if (other.codigo != null)
				return false;
		} else if (!codigo.equals(other.codigo))
			return false;
		return true;
	}
	@Override
	public String toString() {
		return "Projeto [codigo=" + codigo + ", nome=" + nome + ", descricao="
				+ descricao + ", dataInicial=" + dataInicial + ", dataFinal="
				+ dataFinal + ", isAtivo=" + isAtivo + "]";
	}
}
